<?php

class Kzend_StringUtil
{
    const CALCUSE_ENCODING = "UCS-2";

    const CHAR_ZERO = '0';
    const MS932 = "MS932";

    const NUMERIC = 1;
    const UPPERCASE_ALPHABET = 2;
    const LOWERCASE_ALPHABET = 3;
    const ASCII_SYMBOL = 4;
    const CONTROL_CHARACTER = 5;

    const SPECIAL_CHARS = "\\(\\)<>@,;:\\\\\\\"\\.\\[\\]";
    const VALID_CHARS = "[^\\s\\(\\)<>@,;:\\\\\\\"\\.\\[\\]]";
    const QUOTED_USER = "(\"[^\"]*\")";
    const ATOM = "[^\\s\\(\\)<>@,;:\\\\\\\"\\.\\[\\]]+";
    const WORD = "([^\\s\\(\\)<>@,;:\\\\\\\"\\.\\[\\]]+|(\"[^\"]*\"))";

    /**
     * check kind of character ...
     * @param char $ch
     * @return number
     */
    public static function checkKindOfCharacter($ch)
    {
        $ch = hexdec(bin2hex($ch));

        if (0x0030 <= $ch && $ch <= 0x0039) {
            return Kzend_StringUtil::NUMERIC;
        }

        if (0x0041 <= $ch && $ch <= 0x005a) {
            return Kzend_StringUtil::UPPERCASE_ALPHABET;
        }

        if (0x0061 <= $ch && $ch <= 0x007a) {
            return Kzend_StringUtil::LOWERCASE_ALPHABET;
        }

        if (0x0020 <= $ch && $ch <= 0x007e) {
            return Kzend_StringUtil::ASCII_SYMBOL;
        }

        if (0x0000 <= $ch && $ch <= 0x001f) {
            return Kzend_StringUtil::CONTROL_CHARACTER;
        }

        return -1;
    }

    /**
     * get kind of character ...
     * @param char $ch
     * @return number
     */
    private static function getCharacterKind($ch)
    {
        $ch = hexdec(bin2hex($ch));

        if (0x0030 <= $ch && $ch <= 0x0039) {
            return Kzend_StringUtil::NUMERIC;
        }

        if (0x0041 <= $ch && $ch <= 0x005a) {
            return Kzend_StringUtil::UPPERCASE_ALPHABET;
        }

        if (0x0061 <= $ch && $ch <= 0x007a) {
            return Kzend_StringUtil::LOWERCASE_ALPHABET;
        }

        if (0x0020 <= $ch && $ch <= 0x007e) {
            return Kzend_StringUtil::ASCII_SYMBOL;
        }

        if (0x0000 <= $ch && $ch <= 0x001f) {
            return Kzend_StringUtil::CONTROL_CHARACTER;
        }

        return -1;
    }

    /**
     * Check is null ...
     * @param string $text
     * @return boolean
     */
    public static function isNil($text)
    {
        return ($text === null || strlen($text) == 0);
    }

    /**
     * Check is array null ...
     * @param array $arr
     * @return boolean
     */
    public static function isNilArray($arr)
    {
        if ($arr === null) {
            return true;
        }

        if (!is_array($arr)) {
            $error = "Kzend_StringUtil::isNilArray arr is not array";
            trigger_error($error, E_USER_ERROR);
            exit;
        }

        if (count($arr) > 0) {
            return false;
        }

        return true;
    }

    /**
     * Convert string to char array ...
     * @param string $str
     * @return array
     */
    private static function arrayCharCalcUseCharset($str)
    {
        $str = mb_convert_encoding($str, Kzend_StringUtil::CALCUSE_ENCODING);

        $len = mb_strlen($str, Kzend_StringUtil::CALCUSE_ENCODING);
        $chs = array();
        for ($i = 0; $i < $len; $i++) {
            $chs[] = mb_substr($str, $i, 1, Kzend_StringUtil::CALCUSE_ENCODING);
        }

        return $chs;
    }

    /**
     * Check is numeric ...
     * @param string $str
     * @return boolean
     */
    public static function isNumeric($str)
    {
        $chs = Kzend_StringUtil::arrayCharCalcUseCharset($str);
        return Kzend_StringUtil::isNumericChars($chs);
    }

    /**
     * Check is numeric ...
     * @param array $chs
     * @return boolean
     */
    private static function isNumericChars($chs)
    {
        $len = count($chs);
        $flag = true;
        for ($i = 0; $i < $len; $i++) {
            $check = Kzend_StringUtil::getCharacterKind($chs[$i]);
            if ($check != Kzend_StringUtil::NUMERIC) {
                $flag = false;
                break;
            }
        }

        return $flag;
    }

    /**
     * Check is alphabet ...
     * @param string $str
     * @return boolean
     */
    public static function isAlphabet($str)
    {
        $chs = Kzend_StringUtil::arrayCharCalcUseCharset($str);
        return Kzend_StringUtil::isAlphabetChars($chs);
    }

    /**
     * Check is alphabet ...
     * @param array $chs
     * @return boolean
     */
    private static function isAlphabetChars($chs)
    {
        $len = count($chs);
        $flag = true;
        for ($i = 0; $i < $len; $i++) {
            $check = Kzend_StringUtil::getCharacterKind($chs[$i]);
            if ($check != Kzend_StringUtil::UPPERCASE_ALPHABET && $check != Kzend_StringUtil::LOWERCASE_ALPHABET) {
                $flag = false;
                break;
            }
        }

        return $flag;
    }

    /**
     * Check is ascii ...
     * @param string $str
     * @return boolean
     */
    public static function isAscii($str)
    {
        $chs = Kzend_StringUtil::arrayCharCalcUseCharset($str);
        return Kzend_StringUtil::isAsciiChars($chs);
    }

    /**
     * Check is ascii ...
     * @param array $chs
     * @return boolean
     */
    private static function isAsciiChars($chs)
    {
        $len = count($chs);
        $flag = true;
        for ($i = 0; $i < $len; $i++) {
            $check = Kzend_StringUtil::getCharacterKind($chs[$i]);
            if ($check != Kzend_StringUtil::ASCII_SYMBOL && $check != Kzend_StringUtil::LOWERCASE_ALPHABET && $check != Kzend_StringUtil::UPPERCASE_ALPHABET && $check != Kzend_StringUtil::NUMERIC && $check != Kzend_StringUtil::CONTROL_CHARACTER) {
                $flag = false;
                break;
            }
        }

        return $flag;
    }

    /**
     * Check is alphanumeric ...
     * @param string $str
     * @return boolean
     */
    public static function isAlphanumeric($str)
    {
        $chs = Kzend_StringUtil::arrayCharCalcUseCharset($str);
        return Kzend_StringUtil::isAlphanumericChars($chs);
    }

    /**
     * Check is alphanumeric ...
     * @param array $chs
     * @return boolean
     */
    private static function isAlphanumericChars($chs)
    {
        $len = count($chs);
        $flag = true;
        for ($i = 0; $i < $len; $i++) {
            $check = Kzend_StringUtil::getCharacterKind($chs[$i]);
            if ($check != Kzend_StringUtil::LOWERCASE_ALPHABET && $check != Kzend_StringUtil::UPPERCASE_ALPHABET && $check != Kzend_StringUtil::NUMERIC) {
                $flag = false;
                break;
            }
        }

        return $flag;
    }

    /**
     * Check is alphanumericsymbol ...
     * @param string $str
     * @return boolean
     */
    public static function isAlphanumericsymbol($str)
    {
        $chs = Kzend_StringUtil::arrayCharCalcUseCharset($str);
        return Kzend_StringUtil::isAlphanumericsymbolChars($chs);
    }

    /**
     * Check is alphanumericsymbol ...
     * @param array $chs
     * @return boolean
     */
    private static function isAlphanumericsymbolChars($chs)
    {
        $len = count($chs);
        $flag = true;
        for ($i = 0; $i < $len; $i++) {
            $check = Kzend_StringUtil::getCharacterKind($chs[$i]);
            if ($check != Kzend_StringUtil::ASCII_SYMBOL && $check != Kzend_StringUtil::LOWERCASE_ALPHABET && $check != Kzend_StringUtil::UPPERCASE_ALPHABET && $check != Kzend_StringUtil::NUMERIC) {
                $flag = false;
                break;
            }
        }

        return $flag;
    }

    /**
     * Check is mail address ...
     * @param string $email
     * @return boolean
     */
    public static function isMailAddress($email)
    {
        if ($email === null || strlen($email) <= 0) {
            return false;
        }

        if (!Kzend_StringUtil::isAlphanumericsymbol($email)) {
            return false;
        }

        if (!mb_ereg("^(.+)@(.+)$", $email, $emgroup)) {
            return false;
        }

        $user = $emgroup[1];
        $domain = $emgroup[2];

        if (!mb_ereg("^" . Kzend_StringUtil::WORD . "(\\." . Kzend_StringUtil::WORD . ")*$", $user)) {
            return false;
        }

        $ipdomain = array();
        if (mb_ereg("^(\\d{1,3})[.](\\d{1,3})[.](\\d{1,3})[.](\\d{1,3})$", $domain, $ipdomain)) {
            for ($i = 0; $i < 4; $i++) {
                $ipatom = $ipdomain[$i + 1];
                if ($ipatom === null || $ipatom > 255) {
                    return false;
                }
            }

            return true;
        }

        if (!mb_ereg("^" . Kzend_StringUtil::ATOM . "(\\." . Kzend_StringUtil::ATOM . ")*$", $domain)) {
            return false;
        }

        return true;
    }

    /**
     * Check is url ...
     * @param string $url
     * @return boolean
     */
    public static function isHttpUrl($url)
    {
        if (Kzend_StringUtil::isNil($url)) {
            return false;
        }

        if (!preg_match("/^https?:\/\/.+$/", $url)) {
            return false;
        }

        return true;
    }

    /**
     * Check length less than $maxLength ...
     * @param string $text
     * @param int $maxLength
     * @return boolean
     */
    public static function isLessThanMaxLength($text, $maxLength)
    {
        return ($text != null && mb_strlen($text) < $maxLength);
    }

    /**
     * Check length less than or equal $maxLength ...
     * @param string $text
     * @param int $maxLength
     * @return boolean
     */
    public static function isLessEqualMaxLength($text, $maxLength)
    {
        return ($text != null && mb_strlen($text) <= $maxLength);
    }

    /**
     * Check length greater than $minLength ...
     * @param string $text
     * @param int $minLength
     * @return boolean
     */
    public static function isGreaterThanMinLength($text, $minLength)
    {
        return ($text != null && mb_strlen($text) > $minLength);
    }

    /**
     * Check length greater than or equal $minLength ...
     * @param string $text
     * @param int $minLength
     * @return boolean
     */
    public static function isGreaterEqualMinLength($text, $minLength)
    {
        return ($text != null && mb_strlen($text) >= $minLength);
    }

    /**
     * Get length of string ...
     * @param string $text
     * @param string $encoding
     * @return int
     */
    public static function length($text, $encoding = "ASCII")
    {
        if ($encoding != "ASCII") {
            $text = mb_convert_encoding($text, $encoding);
        }

        return mb_strlen($text, $encoding);
    }

    /**
     * Get byte size of string ...
     * @param string $text
     * @param string $encoding
     * @return int
     */
    public static function byteSize($text, $encoding = "ASCII")
    {
        if ($encoding != "ASCII") {
            $text = mb_convert_encoding($text, $encoding);
        }

        return Kzend_StringUtil::length($text, "ASCII");
    }

    /**
     * Check byte length less than max byte length ...
     * @param string $text
     * @param int $maxLength
     * @return boolean
     */
    public static function isLessThanMaxByteLength($text, $maxLength)
    {
        if ($text == null)
            return false;

        $byteLength = Kzend_StringUtil::byteSize($text);
        return ($byteLength < $maxLength);
    }

    /**
     * Check byte length less than or equal max byte length ...
     * @param string $text
     * @param int $maxLength
     * @return boolean
     */
    public static function isLessEqualMaxByteLength($text, $maxLength)
    {
        if ($text == null)
            return false;

        $byteLength = Kzend_StringUtil::byteSize($text);
        return ($byteLength <= $maxLength);
    }

    /**
     * Check byte length greater than min byte length
     * @param string $text
     * @param int $minLength
     * @return boolean
     */
    public static function isGreaterThanMinByteLength($text, $minLength)
    {
        if ($text == null)
            return false;

        $byteLength = Kzend_StringUtil::byteSize($text);
        return ($byteLength > $minLength);
    }

    /**
     * Check byte length greater than or equal min byte length
     * @param string $text
     * @param int $minLength
     * @return boolean
     */
    public static function isGreaterEqualMinByteLength($text, $minLength)
    {
        if ($text == null)
            return false;

        $byteLength = Kzend_StringUtil::byteSize($text);
        return ($byteLength >= $minLength);
    }

    /**
     * Check length of string in range min-max ...
     * @param string $str
     * @param int $min
     * @param int $max
     * @return boolean
     */
    public static function checkLength($str, $min, $max)
    {
        if ($str == null)
            return false;

        $len = mb_strlen($str);
        return ($min <= $len && $len <= $max);
    }

    /**
     * Check byte length of string in range min-max...
     * @param string $str
     * @param int $min
     * @param int $max
     * @param string $encoding
     * @return boolean
     */
    public static function checkByteLength($str, $min, $max, $encoding = "ASCII")
    {
        if ($str == null)
            return false;

        $byteLength = Kzend_StringUtil::byteSize($str, $encoding);
        return ($min <= $byteLength && $byteLength <= $max);
    }

    /**
     * Convert string base on cvmap array
     * @param string $text
     * @param array $cvmap
     * @return string
     */
    public static function convertStringMap($text, $cvmap)
    {
        foreach ($cvmap as $key => $val) {
            $text = str_replace($key, $val, $text);
        }

        return $text;
    }
}

?>
